import { Global, Logger, Module, ValidationPipe } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as dotenv from 'dotenv';
import * as Joi from 'joi';
import { TypeOrmModule } from '@nestjs/typeorm';
import { buildConnectionOptions } from '../ormconfig';
import { UserModule } from '@/modules/system/user/user.module';
import { RoleModule } from '@/modules/system/role/role.module';
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core';
import { AuthModule } from '@/modules/system/auth/auth.module';
import { JwtAuthGuard } from '@/guard/jwt-auth.guard';
import { UserRoleModule } from './modules/system/user-role/user-role.module';
import { ConfigModule as ConfigInfoModule } from '@/modules/system/config/config.module';
import { DictModule } from '@/modules/system/dict/dict.module';
import { LogModule } from '@/modules/system/log/log.module';
import { GlobalExceptionFilter } from '@/filters/global-exception.filter';
import { HttpExceptionFilter } from '@/filters/http-exception.filter';
import { ScheduleModule } from '@nestjs/schedule';
import { TasksModule } from '@/schedule/tasks.module';
import { MenuModule } from './modules/system/menu/menu.module';
import { RoleMenuModule } from './modules/system/role-menu/role-menu.module';
import { ApiModule } from './modules/system/api/api.module';
import { RoleApiModule } from './modules/system/role-api/role-api.module';
import { UserSubuserModule } from './modules/system/user-subuser/user-subuser.module';
import { OssModule } from './modules/system/oss/oss.module';
import { TransformInterceptor } from '@/interceptors/transform.interceptor';
import { FileModule } from '@/modules/system/file/file.module';

// 1. 定义环境文件路径（优先加载 .env，再加载环境特定文件）
const envFilePath = [
    `.env.${process.env.NODE_ENV || 'development'}`, // 环境特定文件（后加载，覆盖前面的）
    '.env', // 基础配置文件（先加载）
];
//将环境变量中字符串形式的 "true" 转换为布尔值 true，但这一转换是由 Joi 验证库 自动完成的，具体针对 schema 中定义为 Joi.boolean() 的字段（如 DB_SYNC、LOG_ON）。
const schema = Joi.object({
    NODE_ENV: Joi.string()
        .valid('development', 'production', 'test')
        .default('development'),
    DB_PORT: Joi.number().default(3306),
    DB_HOST: Joi.alternatives().try(Joi.string().ip(), Joi.string().domain()),
    DB_TYPE: Joi.string().valid('mysql', 'postgres'),
    DB_DATABASE: Joi.string().required(),
    DB_USERNAME: Joi.string().required(),
    DB_PASSWORD: Joi.string().required(),
    DB_SYNC: Joi.boolean().default(false),
    DB_LOG_ON: Joi.boolean().default(false),
    LOG_ON: Joi.boolean(),
    LOG_LEVEL: Joi.string(),
    FILE_SERVE_ROOT: Joi.string(),
    TIME_ZONE: Joi.string(),
});

@Global()
@Module({
    imports: [
        ConfigModule.forRoot({
            isGlobal: true,
            envFilePath,
            // https://github.com/nestjs/config/issues/209#issuecomment-625765057
            // load方法需要自己加入验证
            // 解决方法：https://dev.to/rrgt19/ways-to-validate-environment-configuration-in-a-forfeature-config-in-nestjs-2ehp
            load: [
                () => {
                    const values = dotenv.config({ path: '.env' });
                    const { error } = schema.validate(values?.parsed, {
                        // 允许未知的环境变量
                        allowUnknown: true,
                        // 如果有错误，不要立即停止，而是收集所有错误
                        abortEarly: false,
                    });
                    if (error) {
                        throw new Error(
                            `Validation failed - Is there an environment variable missing?
                         ${error.message}`,
                        );
                    }
                    return values;
                },


            ],
            validationSchema: schema,
        }),
        ScheduleModule.forRoot(),
        // Redis集成
        // RedisModule.forRootAsync({
        //   useFactory: (configService: ConfigService, logger: LoggerService) => {
        //     const host = configService.get(ConfigEnum.REDIS_HOST);
        //     const port = configService.get(ConfigEnum.REDIS_PORT);
        //     const password = configService.get(ConfigEnum.REDIS_PASSWORD);
        //     const url = password
        //       ? `redis://${password}@${host}:${port}`
        //       : `redis://${host}:${port}`;
        //     return {
        //       config: {
        //         url,
        //         reconnectOnError: (err) => {
        //           logger.error(`Redis Connection error: ${err}`);
        //           return true;
        //         },
        //       },
        //     };
        //   },
        //   inject: [ConfigService, Logger],
        // }),
        TypeOrmModule.forRootAsync({
            imports: [ConfigModule], // 确保导入 ConfigModule
            inject: [ConfigService], // 注入 ConfigService
            useFactory: async (configService: ConfigService) => {
                // 从 ConfigService 中获取环境变量，而非直接读 process.env
                return buildConnectionOptions(configService);
            },
        }),
        UserModule,
        RoleModule,
        AuthModule,
        UserRoleModule,
        ConfigInfoModule,
        DictModule,
        LogModule,
        TasksModule,
        MenuModule,
        RoleMenuModule,
        ApiModule,
        RoleApiModule,
        UserSubuserModule,
        OssModule,
        FileModule,
    ],
    controllers: [],
    providers: [
        Logger,
        //注册全局守卫
        {
            provide: APP_GUARD,
            useClass: JwtAuthGuard,
        },
        // 3. 全局管道：ValidationPipe（替代 main.ts 中的 useGlobalPipes）
        {
            provide: APP_PIPE,
            useValue: new ValidationPipe({
                transform: true,
                transformOptions: { enableImplicitConversion: true },
                whitelist: true,
            }),
        },
        // 注册全局拦截器
        {
            provide: APP_INTERCEPTOR,
            useClass: TransformInterceptor,
        },
        //注册全局过滤器
        {
            provide: APP_FILTER,
            useClass: GlobalExceptionFilter, //全局错误拦截
        },
        {
            provide: APP_FILTER,
            useClass: HttpExceptionFilter,//全局http过滤器
        },

    ],
    // exports: [Logger],// 可选：显式导出（但全局模块的 providers 默认已全局可用）
})
export class AppModule {
}
